#!/bin/bash

unset Param_Source_Array # 用于获取传入脚本的参数的工具的变量
unset Param_Source_Size  # 用于获取传入脚本的参数的工具的变量
unset Param_Result       # 用于获取传入脚本的参数的工具的变量

build_log_file=${PWD}/.build_log

function param_init() {
	# 获取传入脚本的参数的工具 - 初始化
	# 将重新记录传入的参数的状况

	Param_Source_Array=($@) # 记录以空格分隔的参数到数组中
	Param_Source_Size=${#@} # 记录参数的个数
}

function param_get() {
	# 获取传入脚本的参数的工具 - 获取指定参数
	# 函数根据输入一个待测试的参数值，来测试这个参数是否存在。
	# 如果存在则返回 0 表示成功，否则返回 1 表示没有这个参数。
	# 如果参数存在，则将参数从数组中删除；此时如果附加参数 1 还会将配置参数的后一个参数删除并值保存到 Param_Result 数组中。
	# 允许匹配多个参数，如果有多个参数匹配，结果都会记录到 Param_Result 数组中。
	# 格式： param_get <测试参数值> [这个参数是否有附加参数]

	if [ ${Param_Source_Size} -lt 1 ]; then
		return 1
	fi

	local i
	local ret=0
	local Param_Num=0

	unset Param_Result
	for ((i = 0; i < ${Param_Source_Size}; i++)); do
		if [ "${Param_Source_Array[$i]:0:2}" == "$1" ]; then
			ret=1
			unset Param_Source_Array[$i]
			if [ "$2" == "1" ] && [ $(($i+1)) -lt ${Param_Source_Size} ]; then
				let i++
				Param_Result[$Param_Num]=${Param_Source_Array[$i]}
				let Param_Num++
				unset Param_Source_Array[$i]
			fi
		fi
	done
	param_init ${Param_Source_Array[@]}

	if [ "${ret}" = "1" ]; then
		return 0
	else
		return 1
	fi
}

IniFile_Get_Option_Line() {
	# 读写配置文件专用函数
	# IniFile_Get_Option_Line <文件路径> <节名> <选项名> [输出变量]
	# 返回： 行号或空值
	# 工作流程
	#    A[开始] --> B[检查文件是否存在]
	#    B --> C{节名是否为-g?}
	#    C -->|是| D[全局查找选项]
	#    C -->|否| E[在指定节内查找选项]
	#    D --> F[返回行号]
	#    E --> F

	local IniFile=$1
	local Section=`echo ${2} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ ][ ]*/ /g'`
	local Option=`echo ${3} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ ][ ]*/ /g'`
	local LineNum

	if [ ! -f ${IniFile} ]; then
		return 1
	fi

	if [ "${Section}" = "-g" ]; then
		LineNum=`sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/=/ = /g' -e 's/[ ][ ]*/ /g' -e 's/\r//g' -n -e "/^${Option} = /=" ${IniFile} | sed -n '$p'`
	else
		LineNum=`sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/=/ = /g' -e 's/\[/\[ /g' -e 's/\]/ \]/g' -e 's/[ ][ ]*/ /g' -e 's/\r//g' -e "0,/^\[ ${Section} ]/d" -e '/^\[.*\]/,$d' -n -e "/^${Option} = /=" ${IniFile} | sed -n '$p'`
	fi

	if [ -z $4 ]; then
		echo ${LineNum}
	else
		eval $4=${LineNum}
	fi
}

function ini_file_read() {
	# 读配置文件
	# ini_file_read <文件路径> <节名> <选项名>
	# 返回： 选项值或空值

	local IniFile=$1
	local Section=`echo ${2} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ ][ ]*/ /g'`
	local Option=`echo ${3} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ ][ ]*/ /g'`
	if [ $# -lt 3 ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} 少于 3 个参数\n"
		return 1
	fi
	if [ -z "${IniFile}" ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} <IniFile> 不能空值\n"
		return 1
	fi
	if [ -z "${Option}" ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} <Option> 不能空值\n"
		return 1
	fi
	if [ -z "${Option}" ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} <Option> 不能空值\n"
		return 1
	fi

	local LineNum=`IniFile_Get_Option_Line "${IniFile}" "${Section}" "${Option}"`
	local IniValue=""
	if [ -n "${LineNum}" ]; then
		IniValue=`sed -n -e "${LineNum}p" ${IniFile} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/=/ = /g' -e 's/[ ][ ]*/ /g' -e 's/\r//g' -e "s/^${Option} = //"`
	fi

	echo ${IniValue}
}

function ini_file_write() {
	# 写配置文件
	# ini_file_write <文件路径> <节名> <选项名> <选项值>
	# 返回： 0 表示成功，1 表示失败

	local IniFile=$1
	local Section=`echo ${2} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ ][ ]*/ /g'`
	local Option=`echo ${3} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ ][ ]*/ /g'`
	local NewValue=`echo ${4} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/[ ][ ]*/ /g'`
	local IniValue

	if [ $# -lt 4 ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} 少于 4 个参数\n"
		return 1
	fi
	if [ -z "${IniFile}" ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} <IniFile> 不能空值\n"
		return 1
	fi
	if [ -z "${Option}" ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} <Option> 不能空值\n"
		return 1
	fi
	if [ -z "${Option}" ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} <Option> 不能空值\n"
		return 1
	fi

	local LineNum=`IniFile_Get_Option_Line "${IniFile}" "${Section}" "${Option}"`
	local IniValue=""
	if [ -n "${LineNum}" ]; then
		IniValue=`sed -n -e "${LineNum}p" ${IniFile} | sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/=/ = /g' -e 's/[ ][ ]*/ /g' -e 's/\r//g' -e "s/^${Option} = //"`
	fi
	if [ "${IniValue}" = "${NewValue}" ]; then
		return 0
	fi

	if [ -n "${LineNum}" ];then
		NewValue=${NewValue//\//\\\/}
		sed -i "${LineNum}s/.*/${3}${5}=${5}${NewValue}/" ${IniFile}
	else
		if [ "${Section}" = "-g" ]; then
			echo "${3}${5}=${5}${NewValue}" >> ${IniFile}
		else
			if [ ! -f ${IniFile} ] || [ -z "`sed -e 's/\[/\[ /g' -e 's/\]/ \]/g' -e 's/\t/ /g' -e 's/[ ][ ]*/ /g' -e 's/^[ \t]*//g' -n -e "/^\[ ${Section} ]/=" ${IniFile}`" ]; then
				echo -e "\n[${Section}]" >> ${IniFile}
				echo "${3}${5}=${5}${NewValue}" >> ${IniFile}
			else
				LineNum=`sed -e 's/\t/ /g' -e 's/^[ \t]*//g' -e 's/[ \t]*$//g' -e 's/=/ = /g' -e 's/\[/\[ /g' -e 's/\]/ \]/g' -e 's/[ ][ ]*/ /g' -e 's/\r//g' -e "0,/^\[ ${Section} ]/d" -e '/^\[.*\]/,$d' -n -e '/ = /=' ${IniFile} | sed -n '$p'`
				if [ -z "${LineNum}" ]; then
					LineNum=`sed -e 's/\[/\[ /g' -e 's/\]/ \]/g' -e 's/\t/ /g' -e 's/[ ][ ]*/ /g' -e 's/^[ \t]*//g' -n -e "/^\[ ${Section} ]/=" ${IniFile}`
				fi
				NewValue=${NewValue//\//\\\/}
				sed -e "${LineNum}a\\${3}${5}=${5}${NewValue}" -i ${IniFile}
			fi
		fi
	fi
}

function choice_folder() {
	# choice_folder <VarTar> <VarSrc> <Title> <SourceDir>
	# param: VarTar      已选择路径的变量
	# param: VarSrc      原始路径的变量
	# param: Title       选项的标题
	# param: SourceDir   初始路径

	# 需要排除的目录名称，可根据需要修改
	local EXCLUDE_DIRS=("architecture" "bin" "release" "debug" "drivers" "include" "kernel" "library" "source" "tools")

	local VarTar
	local VarSrc
	local DefaultSel
	local Title=$3
	local SourceDir=${4%*/}
	local choice
	local item
	local answer
	local result
	local Choices_Array=()
	local Answer_Array
	local i=0

	[ $# -lt 3 ] && ${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} 少于 3 个参数\n" && return 1
	[ "$4" == "/" ] && SourceDir="/"
	[ -z "${SourceDir}" ] && SourceDir=/
	[ ! -d "${SourceDir}" ] && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}: No such directory '${SourceDir}'" && return 1
	SourceDir=${SourceDir%*/}

	eval VarTar=\$$1
	eval VarSrc=\$$2

	VarTar=${VarTar%*/}
	VarTar=${VarTar#/*}
	VarSrc=${VarSrc%*/}
	VarSrc=${VarSrc#/*}

	while [ -n "${VarTar}" ] && [ ! -d "${SourceDir}/${VarTar}" ]; do
		VarTar="/${VarTar}"
		VarTar=${VarTar%/*}
		VarTar=${VarTar#/*}
		VarSrc=""
	done

	DefaultSel=${VarSrc%%/*}
	if [ ! -d "${SourceDir}/${VarTar}/${DefaultSel}" ]; then
		DefaultSel=""
	fi

	# 遍历当前目录下的子目录，并排除指定名称的目录
	for item in `ls -1 "${SourceDir}/${VarTar}"`; do
		if [ -d "${SourceDir}/${VarTar}/$item" ]; then
			local skip=0
			for ex in "${EXCLUDE_DIRS[@]}"; do
				if [ "$item" == "$ex" ]; then
					skip=1
					break
				fi
			done
			[ $skip -eq 0 ] && Choices_Array=(${Choices_Array[@]} "$item")
		fi
	done

	while :; do
		if [ ${#Choices_Array[@]} -eq 0 ]; then
			echo
			echo -e "\033[33m[WARN]\033[0m ${BASH_SOURCE}: No directory for choice"
			echo
			echo -e "Current choice: \033[0m${SourceDir}/${VarTar}\033[0m"
			echo
			echo -e "${Title}"

			answer=""
			while [ -z "${answer}" ]; do
				read -p "Input manual: " answer
			done
		else
			echo
			echo -e "\033[34m----==== Directory list ====----\033[0m"
			echo
			i=0
			for choice in ${Choices_Array[@]}; do
				i=$(($i+1))
				echo "     $i. $choice"
			done
			echo
			echo -e "Current choice: \033[0m${SourceDir}/${VarTar}\033[0m"
			echo
			echo -e "${Title}"
			
			if [ -z "${DefaultSel}" ] && [ "$i" == "1" ] && [ -z "${VarSrc}" ]; then
				DefaultSel=${Choices_Array[0]}
			fi
			if [ -z "${DefaultSel}" ]; then
				answer=""
				while [ -z "${answer}" ]; do
					read -p "Which would you like? " answer
				done
			else
				read -p "Which would you like? [${DefaultSel}] " answer
			fi
		fi
		echo

		if [ -z "$answer" ]; then
			result=${DefaultSel}
			break
		elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") && [ $answer -le ${#Choices_Array[@]} ] && [ $answer -ne 0 ]; then
			result=${Choices_Array[$(($answer-1))]}
			break
		elif [ "${answer}" == "." ]; then
			return 0
		elif [ "${answer}" == "/" ]; then
			eval $2=${VarTar}/${VarSrc}
			eval $1=""
			return 0
		elif [ "${answer}" == ".." ]; then
			[ -z "${VarTar}" ] && return 0
			eval $2=${VarTar##*/}/${VarSrc}
			VarTar="/${VarTar}"
			VarTar=${VarTar%/*}
			VarTar=${VarTar#/*}
			eval $1=${VarTar}
			return 0
		elif [ -d "${SourceDir}/${VarTar}/${answer}" ]; then
			result=$answer
			break
		else
			i=0
			Answer_Array=()
			for tmp in ${Choices_Array[@]}; do
				if (echo $tmp | grep -q -e "${answer}"); then
					Answer_Array=(${Answer_Array[@]} ${tmp})
					i=$(($i+1))
				fi
			done
			if [ $i -eq 0 ]; then
				break
			elif [ $i -eq 1 ]; then
				result=${Answer_Array[0]}
				break
			else
				Choices_Array=(${Answer_Array[@]})
			fi
		fi
	done

	result=${result#/*}
	result=${result%*/}
	VarTar=${VarTar}/${result}
	VarTar=${VarTar#/*}
	if [ ! -d ${SourceDir}/${VarTar} ]; then
		echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}: No such directory '${SourceDir}'"
		sleep 1
		return 1
	fi

	if [ "${DefaultSel}" == "${result}" ]; then
		VarSrc="${VarSrc}/"
		VarSrc=${VarSrc#*/}
		VarSrc=${VarSrc%*/}
	else
		VarSrc=""
	fi

	eval $1=${VarTar}
	eval $2=${VarSrc}
}



function choice_file() {

	local Title=$2
	local SourceDir=${3%/}
	local DefaultSel=$5
	local Match=.*
	local choice
	local item
	local answer
	local result
	local Choices_Array=()
	local Answer_Array=()
	local i=0

	if [ $# -lt 3 ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} 少于 3 个参数\n"
		return 1
	fi

	if [ -z "${SourceDir}" ]; then
		${BASH_SOURCE} -l ${FUNCNAME} -a && echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} <SourceDir> 不能空值\n"
		return 1
	fi

	[ ! -d "${SourceDir}" ] && { echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} No such directory '${SourceDir}'"; return 1; }

	[ -n "$4" ] && Match=$4
	for item in `ls -1 ${SourceDir}`;do
		if [ -f ${SourceDir}"/"$item ]; then
			if (echo $item | grep -q -e "${Match}"); then
				Choices_Array=(${Choices_Array[@]} $item)
			fi
		fi
	done

	while :; do
		if [ ${#Choices_Array[@]} -eq 0 ]; then
			echo
			echo -e "\033[33m[WARN]\033[0m ${BASH_SOURCE}: No file for choice"
			echo
			echo -e "Current location: \033[0m${SourceDir}/${VarTar}\033[0m"
			echo
			echo -e "${Title}"

			answer=""
			while [ -z "${answer}" ]; do
				read -p "Input manual: " answer
			done
		else
			echo
			echo -e "\033[34m----==== File list ====----\033[0m"
			echo
			i=0
			for choice in ${Choices_Array[@]}; do
				i=$(($i+1))
				echo "     $i. $choice"
			done
			echo
			echo -e "Current location: \033[0m${SourceDir}/${VarTar}\033[0m"
			echo
			echo -e "${Title}"

			if [ -z "${DefaultSel}" ] && [ "$i" == "1" ]; then
				DefaultSel=${Choices_Array[0]}
			fi
			if [ -z "${DefaultSel}" ]; then
				answer=""
				while [ -z "${answer}" ]; do
					read -p "Which would you like? " answer
				done
			else
				read -p "Which would you like? [${DefaultSel}] " answer
			fi
		fi
		echo

		if [ -z "$answer" ]; then
			result=${DefaultSel}
			break
		elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") && [ $answer -le ${#Choices_Array[@]} ] && [ $answer -ne 0 ]; then
			result=${Choices_Array[$(($answer-1))]}
			break
		elif [ -f "${SourceDir}/${VarTar}/${answer}" ]; then
			result=$answer
			break
		else
			i=0
			Answer_Array=()
			for tmp in ${Choices_Array[@]}; do
				if (echo $tmp | grep -q -e "${answer}"); then
					Answer_Array=(${Answer_Array[@]} ${tmp})
					i=$(($i+1))
				fi
			done
			if [ $i -eq 0 ]; then
				continue
			elif [ $i -eq 1 ]; then
				result=${Answer_Array[0]}
				break
			else
				Choices_Array=(${Answer_Array[@]})
			fi
		fi
	done

	eval $1=$result
}



function choice_target() {
	# 专用于选择项目的目录
	# choice_target <output> <当前的选项默认值> <FuncName>

	local Default_Tar=$2
	local Func_Name=$3
	local Choices_Array=()
	local Answer_Array=()
	local answer=""
	local tmp
	local i=0

	for tmp in `sed -n -e '/\[.*]/p' ${build_log_file}`; do # 读取配置文件 ${build_log_file} 中的所有节名
		if [ "$tmp" != "[${Func_Name}]" ]; then
			tmp=${tmp#*[}
			tmp=${tmp%]*}
			tmp=${tmp//::/\/}
			Choices_Array=(${Choices_Array[@]} ${tmp})
		fi
	done

	if [ ${#Choices_Array[@]} -ne 0 ]; then
		while :; do
			if [ ${#Choices_Array[@]} -ne 0 ]; then
				echo
				echo -e "\033[34m----==== Targets list ====----\033[0m"
				echo
				echo -e "\033[32m     0. New target ...\033[0m"
				i=0
				for tmp in ${Choices_Array[@]}; do
					i=$(($i+1))
					echo "     $i. $tmp"
				done
				echo
				echo -e "Current location: \033[0m./${Default_Tar}\033[0m"
				echo
				echo -e "Choice \033[33mproject\033[0m"
				if [ -n "${Default_Tar}" ]; then
					read -p "Which would you like? [${Default_Tar}] " answer
				else
					read -p "Which would you like? [0] " answer
				fi
			fi

			if [ -z "$answer" ]; then
				answer=${Default_Tar}
				break
			elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") && [ $answer -eq 0 ]; then
				answer=""
				break
			elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") && [ $answer -le ${#Choices_Array[@]} ]; then
				Default_Tar=${Choices_Array[$(($answer-1))]}
				answer=${Default_Tar}
				break
			else
				i=0
				Answer_Array=()
				for tmp in ${Choices_Array[@]}; do
					if (echo $tmp | grep -q -e "${answer}"); then
						Answer_Array=(${Answer_Array[@]} ${tmp})
						i=$(($i+1))
					fi
				done
				if [ $i -eq 0 ]; then
					continue
				elif [ $i -eq 1 ]; then
					answer=${Answer_Array[0]}
					break
				else
					Choices_Array=(${Answer_Array[@]})
				fi
			fi
		done
	fi

	eval $1=${answer}
}



function choice_toolchain() {

	local Default_Tar=$2
	local Func_Name=$3
	local Choices_Array=()
	local Answer_Array=()
	local answer
	local tmp
	local i=0

	for tmp in `sed -n -e '/toolchain[1-9][0-9]*[ \t]*=[ \t]*/p' ${build_log_file} | sed -e 's/toolchain[1-9][0-9]*[ \t]*=[ \t]*//g'`; do
		if !(echo " ${Choices_Array[@]} " | grep -q -e " ${tmp} "); then
			Choices_Array=(${Choices_Array[@]} ${tmp})
		fi
	done

	if [ ${#Choices_Array[@]} -ne 0 ]; then
		while :; do
			if [ ${#Choices_Array[@]} -ne 0 ]; then
				echo
				echo -e "\033[34m----==== Tool chain list ====----\033[0m"
				echo
				echo -e "\033[32m     0. New target ...\033[0m"
				i=0
				for tmp in ${Choices_Array[@]}; do
					i=$(($i+1))
					echo "     $i. $tmp"
				done
				echo
				echo -e "Current choice: \033[0m${Default_Tar}\033[0m"
				echo
				echo -e "Choice or input \033[33mtool chain\033[0m"
				if [ -n "${Default_Tar}" ]; then
					read -p "Which would you like? [${Default_Tar}] " answer
				else
					read -p "Which would you like? " answer
				fi
			fi

			if [ -z "$answer" ]; then
				answer=${Default_Tar}
				if [ -n "${answer}" ]; then
					break
				fi
			elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") && [ $answer -eq 0 ]; then
				answer=""
				break
			elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$") && [ $answer -le ${#Choices_Array[@]} ]; then
				Default_Tar=${Choices_Array[$(($answer-1))]}
				answer=${Default_Tar}
				break
			else
				i=0
				Answer_Array=()
				for tmp in ${Choices_Array[@]}; do
					if (echo $tmp | grep -q -e "${answer}"); then
						Answer_Array=(${Answer_Array[@]} ${tmp})
						i=$(($i+1))
					fi
				done
				if [ $i -eq 0 ]; then
					continue
				elif [ $i -eq 1 ]; then
					answer=${Answer_Array[0]}
					break
				else
					Choices_Array=(${Answer_Array[@]})
				fi
			fi
		done
	fi

	eval $1=${answer}
}


function find_common_path() {
	# 求解两个目录的共同基础目录
	# find_common_path <path1> <path2>
	# 返回： 共同基础目录
	# 过程：
	# 1. 将两个路径拆分为目录数组
	# 2. 从前向后比较，找到第一个不同的目录
	# 3. 返回共同部分
	# 使用示例:
	# path1="/home/user/project/src"
	# path2="/home/user/test/data"
	# common=$(find_common_path "$path1" "$path2")
	# 输出: /home/user

	local path1=$(realpath "$1")
	local path2=$(realpath "$2")

	# 转换为数组
	IFS='/' read -ra arr1 <<< "$path1"
	IFS='/' read -ra arr2 <<< "$path2"

	# 找到最短长度
	local min_len=$((${#arr1[@]} < ${#arr2[@]} ? ${#arr1[@]} : ${#arr2[@]}))

	# 从前向后比较
	local common="/"
	for ((i=1; i<min_len; i++)); do
		if [ "${arr1[$i]}" = "${arr2[$i]}" ]; then
			common="$common${arr1[$i]}/"
		else
			break
		fi
	done

	echo "${common%/}"
}


function --build() {
	# 编译项目
	#
	# build [-p] [-t] [-n] [-a] [-c] [-l]
	# param: -p <param>  (Project config) 定义配置文件，这将在项目的目录下，筛选格式为 "^参数.*.conf$"。支持设置多个参数
	# param: -t          (Target project) 表示仅重新选择项目
	# param: -n          (New config) 表示仅选择配置文件编译
	# param: -a          (All) 表示重新选择设置编译
	# param: -c          (Clean) 清除工程
	# param: -l          (List config) 仅打印工程配置
	#
	# 对于未识别的参数，将直接传递到Makefile
	#
	# 示例: 仅编译
	# build -p prj -p FP
	#
	# 示例: 仅选择配置文件编译
	# build -p prj -p FP -n
	#
	# 示例: 重新选择设置编译
	# build -p prj -p FP -a
	#
	# 示例: 参数传递
	# build help

	local PrjFile_Array
	local Build_New        # 标记对应传入参数 -n
	local Build_All        # 标记对应传入参数 -a
	local Build_Target     # 标记对应传入参数 -t
	local Build_Clean      # 标记对应传入参数 -c
	local Build_List       # 标记对应传入参数 -l
	local Build_Log        # 用于比较路径的关键信息，如果路径发生变化则删除编译过程文件并重新选择配置
	local rtk_base         # 从 .build_log 文件中读取的 RTK 的绝对路径
	local Prj_Path         # 从 .build_log 文件中读取的 工程目录的相对 ${PWD} 的路径
	local Prj_Base         # 工程目录的绝对路径
	local Prj_Name         # Prj_Path 的别名，使用 "::" 代替 "/" ，用于在配置文件 .build_log 中的节名
	local Board_Path
	local Board_Name
	local Chip_Path
	local Chip_Name
	local Rules_Path
	local ToolChain
	local ConfFiles
	local ConfFile_New
	local ConfFile_Array
	local ChoiceFile_Array
	local MakeFileParam
	local RebuildParam
	local Flag
	local tmp
	local i
	local j

	ConfFile_New=""

	# 解析传入的参数并根据参数标记对应的变量
	if [ $# -ne 0 ]; then

		param_init $@
		param_get "-t" && Build_Target=1
		param_get "-n" && Build_New=1 && clear
		param_get "-a" && Build_All=1 && clear
		param_get "-c" && Build_Clean=1
		param_get "-l" && Build_List=1
		param_get "-p" 1 && [ ${#Param_Result[@]} -ne 0 ] && {
			for tmp in ${Param_Result[@]}; do
				ConfFile_New=${ConfFile_New}${tmp},
			done
		}

	fi

#########################################################################################################

	# 读取 [--build] 下的路径配置
	rtk_base=`ini_file_read ${build_log_file} "${FUNCNAME}" "rtk_base"`
	Prj_Path=`ini_file_read ${build_log_file} "${FUNCNAME}" "project_path"`
	if [ ! -f "${rtk_base}/rtk.build.sh" ]; then
		rtk_base=""
	fi

	if [ -n "${rtk_base}" ]; then
		# rtk_base 转为绝对路径，删除多余的字符 '/'
		rtk_base=`readlink -e ${rtk_base}`
		rtk_base=${rtk_base%*/}
	fi

	# 记录 Build_Log 用于比较路径的关键信息
	Build_Log=${rtk_base}::${Prj_Path}

	# 确认 rtk_base 是否为空值，如果为空值则提示错误信息
	if [ -z "${rtk_base}" ]; then
		rtk_base=$(dirname $(which rtk.build.sh))
		if [ -z "${rtk_base}" ]; then
			echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} Please run export.sh from rtk directory"
			return 1
		fi
		Prj_Path=""
	fi


#########################################################################################################

	if [ -f ${PWD}/Makefile ] && (grep -q -e "include[ \t].*/config.mk" ${PWD}/Makefile); then # 当前目录就是工程目录

		Prj_Path="."
		Prj_Base=${PWD}

	else # 当前目录不是工程目录，可能需要重新选择 Project

		# 规范化 Prj_Path 删除前后的字符 '/'
		Prj_Path=${Prj_Path#/*}
		Prj_Path=${Prj_Path%*/}

		if [ -n "${Build_Target}" ] && [ -n "${Prj_Path}" ] && [ -z "${Build_All}" ]; then # 仅重新选择项目，判断方法：配置文件有记录时，传入参数 -t ，没有传入参数 -a （如果传入了参数 -a 会在后面处理）

			# 重新选择项目
			local New_Target
			while :; do
				choice_target New_Target ${Prj_Path} ${FUNCNAME}
				if [ -z "${New_Target}" ]; then # 如果没有选择项目，直接退出，这将直接使用之前的配置 Prj_Path
					Prj_Base=""
					break
				fi

				if [ -d ${PWD}/${New_Target} ] \
				&& [ -f ${PWD}/${New_Target}/Makefile ] \
				&& (grep -q -e "include[ \t].*/config.mk" ${PWD}/${New_Target}/Makefile)
				then
					Prj_Path=${New_Target}
					Prj_Base=${PWD}/${Prj_Path}
					break
				else
					echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} No such directory '${Prj_Path}'"
					sleep 1
				fi
			done
		fi

		# 重新选择项目，或者没有记录的项目
		if [ -z "${Prj_Base}" ]; then
			Prj_Path=${Prj_Path#/}
			if [ -n "${Build_All}${Build_Target}" ] || [ -z "${Prj_Path}" ]; then
				tmp=${Prj_Path}
				Prj_Path=""
			fi
			while :; do
				if [ -n "${Prj_Path}" ] \
				&& [ -d ${PWD}/${Prj_Path} ] \
				&& [ -f ${PWD}/${Prj_Path}/Makefile ] \
				&& (grep -q -e "include[ \t].*/config.mk" ${PWD}/${Prj_Path}/Makefile)
				then
					break
				fi
				choice_folder Prj_Path tmp "Choice \033[33mproject-path\033[0m" ${PWD}
			done
			Prj_Base=${PWD}/${Prj_Path}
		fi

	fi

	# 保存 [--build] 下的所有配置
	if [ "${Build_Log}" != "${rtk_base}::${Prj_Path}" ]; then
		rm -rf ${rtk_base}/debug/project.*
		rm -rf ${rtk_base}/debug/symbols.txt
	fi
	ini_file_write ${build_log_file} "${FUNCNAME}" "rtk_base" ${rtk_base} ' '
	ini_file_write ${build_log_file} "${FUNCNAME}" "project_path" ${Prj_Path} ' '

#########################################################################################################

	# 读取 [${Prj_Name}] 下的板级配置
	Prj_Name=${Prj_Path//\//::}
	Board_Path=`ini_file_read ${build_log_file} "${Prj_Name}" "board"`

#########################################################################################################

	Board_Path=${Board_Path#/}
	Board_Path=${Board_Path%/}
	Board_Name=${Board_Path##*/}
	Flag=""

	if [ -z "${Board_Name}" ] || [ -n "${Build_All}${Build_New}" ]; then

		Board_Path=/${Board_Path#/}
		# 选择 board
		if [ -n "${Build_Clean}" ]; then
			tmp=${Board_Path##*/}
			Board_Path=${Board_Path%/*}
		else
			tmp=${Board_Path#*/}
			Board_Path=${Board_Path%%/*}
		fi
		while :; do
			if [ -n "${Board_Path}" ] \
			&& [ -d ${rtk_base}/architecture/board/${Board_Path} ] \
			&& [ -n "`find ${rtk_base}/architecture/board/${Board_Path} -maxdepth 1 -type f -name *.mk`" ]
			then
				break
			fi
			choice_folder Board_Path tmp "Choice \033[33mboard-path\033[0m" ${rtk_base}/architecture/board
		done
		Board_Path=${Board_Path#/}
		Board_Name=${Board_Path##*/}

	elif [ -n "${Build_Clean}" ]; then

		mkdir -p ${Prj_Base}/outdir/${Board_Name}

		# 计算输出目录数
		i=0
		if [ -d ${Prj_Base}/outdir ]; then
			for tmp in `ls -1 ${Prj_Base}/outdir`; do
				if [ -d ${Prj_Base}/outdir/$tmp ]; then
					let i++
				fi
			done
		fi

		# 多于一个目录时提供选择
		if (($i > 1)); then
			tmp="${Board_Name}"
			while :; do
				choice_folder Flag tmp "Choice \033[33mclean-path\033[0m" ${Prj_Base}/outdir/
				if [ -n "${Flag}" ] \
				&& [ -d ${Prj_Base}/outdir/${Flag} ]
				then
					break
				fi
			done
			if [ "${Flag}" == "${Board_Name}" ]; then
				Flag=""
			else
				Board_Name=${Flag}
			fi
		fi

	fi

	# 根据参数 -c 清除中间文件
	if [ -n "${Build_Clean}" ]; then
		if [ -d ${Prj_Base}/outdir/${Board_Name}/ ]; then
			rm -rf ${rtk_base}/debug/project.*
			rm -rf ${rtk_base}/debug/symbols.txt
			rm -rf ${Prj_Base}/outdir/${Board_Name}/ || return 1
		fi
		echo -e "\n[SUCCESS] Clean build out directory: ${Prj_Base}/outdir/${Board_Name}/\n"

		if [ -z "${Build_Target}${Build_New}${Build_All}" ] && [ ${#Param_Source_Array[@]} -eq 0 ]; then
			return 0
		fi

		if [ -n "${Flag}" ]; then
			if [ ${#Param_Source_Array[@]} -ne 0 ]; then
				echo -e "\033[33m[WARN]\033[0m ${BASH_SOURCE}: '${Board_Name}' is not current board code. Terminate operation"
			fi
			return 0
		fi
	fi


#########################################################################################################

	# 读取 [${Prj_Name}] 下的板级对应配置
	Chip_Path=`ini_file_read ${build_log_file} "${Prj_Name}" "${Board_Name}::chip"`
	Rules_Path=`ini_file_read ${build_log_file} "${Prj_Name}" "${Board_Name}::rules"`
	ToolChain=`ini_file_read ${build_log_file} "${Prj_Name}" "${Board_Name}::toolchain"`
	ConfFiles=`ini_file_read ${build_log_file} "${Prj_Name}" "${Board_Name}::conf"`

	# 标记 Build_Log 用于比较旧板级配置，以确认是否需要清除工程
	Build_Log=${rtk_base}:${Prj_Path}:${Board_Path}:${Chip_Path}:${Rules_Path}:${ToolChain}:${ConfFiles}

#########################################################################################################

	# 选择 chip
	Chip_Path=/${Chip_Path#/}
	Chip_Path=${Chip_Path%/}
	if [ -n "${Build_All}" ] || [ -z "${Chip_Path}" ]; then
		tmp=${Chip_Path#*/}
		Chip_Path=${Chip_Path%%/*}
	fi
	while :; do
		if [ -n "${Chip_Path}" ] \
		&& [ -d ${rtk_base}/architecture/chip/${Chip_Path} ] \
		&& [ -n "`find ${rtk_base}/architecture/chip/${Chip_Path} -maxdepth 1 -type f -name *.mk`" ]
		then
			break
		fi
		choice_folder Chip_Path tmp "Choice \033[33mchip-path\033[0m" ${rtk_base}/architecture/chip
	done
	Chip_Path=${Chip_Path#/}
	Chip_Name=${Chip_Path##*/}


#########################################################################################################

	# 选择 rules
	Rules_Path=/${Rules_Path#/}
	Rules_Path=${Rules_Path%/}
	if [ -n "${Build_All}" ] || [ -z "${Rules_Path}" ]; then
		tmp=${Rules_Path#*/}
		Rules_Path=${Rules_Path%%/*}
	fi
	while :; do
		if [ -n "${Rules_Path}" ] \
		&& [ -d ${rtk_base}/architecture/arch/${Rules_Path} ] \
		&& [ -f ${rtk_base}/architecture/arch/${Rules_Path}/cc.mk ]
		then
			break
		fi
		choice_folder Rules_Path tmp "Choice \033[33mrules-path\033[0m" ${rtk_base}/architecture/arch
	done
	Rules_Path=${Rules_Path#/}

	# 保存配置记录
	ini_file_write ${build_log_file} "${Prj_Name}" "board" ${Board_Path} ' '
	ini_file_write ${build_log_file} "${Prj_Name}" "${Board_Name}::chip" ${Chip_Path} ' '
	ini_file_write ${build_log_file} "${Prj_Name}" "${Board_Name}::rules" ${Rules_Path} ' '

#########################################################################################################

	# 选择 toolchain
	if [ "${ToolChain}" == "" ]; then
		tmp=""
	else
		tmp=`which ${ToolChain}`
	fi
	if [ "$?" != '0' ] || [ -n "${Build_All}" ] || !(echo ${tmp} | grep -q -e "gcc$"); then
		choice_toolchain ToolChain ${ToolChain}
		echo
	fi
	if [ -z "${ToolChain}" ]; then
		while [ -z "${ToolChain}" ]; do
			read -p "Input GCC path: " ToolChain
		done
	fi
	tmp=`which ${ToolChain}`
	if [ "$?" != '0' ]; then
		echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} Tool chain not found '${ToolChain}'"
		exit 1
	fi
	if !(echo ${tmp} | grep -q -e "gcc$"); then
		echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} Not gcc tool chain '${ToolChain}'"
		exit 1
	fi

	# 检查是否已经存在，如果不存在则添加
	i=0
	while :; do
		let i++
		tmp=`ini_file_read ${build_log_file} "${FUNCNAME}" "toolchain${i}"`
		if [ -z "${tmp}" ]; then
			ini_file_write ${build_log_file} "${FUNCNAME}" "toolchain${i}" ${ToolChain} ' '
			break
		elif [ "${tmp}" = "${ToolChain}" ]; then
			break
		fi
	done

	# 保存配置记录
	ini_file_write ${build_log_file} "${Prj_Name}" "${Board_Name}::toolchain" ${ToolChain} ' '


#########################################################################################################

	# 解析配置文件 ${PrjFile_Array[@]}
	if !(echo ${ConfFile_New} | grep -q -e ','); then
		ConfFile_New=${ConfFiles}
	fi
	if !(echo ${ConfFile_New} | grep -q -e ','); then
		ConfFile_New="prj,"
	fi
	ConfFiles=${ConfFile_New}
	PrjFile_Array=()
	tmp=${ConfFiles}
	while [ "${tmp}" != "" ]; do
		PrjFile_Array=(${PrjFile_Array[@]} ${tmp%%,*})
		tmp=${tmp#*,}
	done

	# 读取配置文件 ${ConfFile_Array[@]}
	Flag=0
	for tmp in ${PrjFile_Array[@]}; do
		tmp=`ini_file_read ${build_log_file} "${Prj_Name}" "${Board_Name}::${tmp//\//::}_conf"`
		if [ -z "${tmp}" ] || [ ! -f ${Prj_Base}/${tmp} ]; then
			Flag=1
		fi
		ConfFile_Array=(${ConfFile_Array[@]} ${tmp})
	done
	# 选择配置文件 ${ChoiceFile_Array[@]}
	if  [ -n "${Build_All}" ] || [ -n "${Build_New}" ] || [ "${Flag}" = "1" ]; then
		i=0
		for tmp in ${PrjFile_Array[@]}; do
			local SrcDir=`dirname $tmp`
			local SrcFile=`basename $tmp`
			if [ "${SrcDir}" == "." ]; then
				SrcDir=""
			else
				SrcDir="${SrcDir}/"
			fi
			choice_file SrcFile "Choice \033[33m${tmp}*.conf\033[0m" ${Prj_Base%/}/${SrcDir} "^${SrcFile}.*.conf$" ${ConfFile_Array[$i]##*/}
			ChoiceFile_Array[$i]=${SrcDir}${SrcFile}
			let i++
		done
	fi

	# 比较指定的配置文件以删除
	Flag=0
	i=0
	for tmp in `echo ${ChoiceFile_Array[@]}`; do
		if (! echo ${ConfFile_Array[@]} | grep -q -e "${tmp}"); then
			echo -e "New config file: ${PrjFile_Array[$i]}_conf = \033[33m$tmp\033[0m"
			Flag=1
		fi
		if [ ! -f "${Prj_Base}/${tmp}" ]; then
			echo -e "\033[31m[ERROR]\033[0m ${BASH_SOURCE}:${LINENO} No such file '${Prj_Base}/${tmp}'"
			return 1
		fi
		ConfFile_Array[$i]=${tmp}
		let i++
	done

	# 删除输出目录
	if [ -z "${Build_Clean}" ]; then
		if [ "${Flag}" = "1" ] || [ "${Build_Log}" != "${rtk_base}:${Prj_Path}:${Board_Path}:${Chip_Path}:${Rules_Path}:${ToolChain}:${ConfFiles}" ]; then
			if [ -d ${Prj_Base}/outdir/${Board_Name}/ ]; then
				rm -rf ${rtk_base}/debug/project.*
				rm -rf ${rtk_base}/debug/symbols.txt
				rm -rf ${Prj_Base}/outdir/${Board_Name}/ || return 1
			fi
			echo -e "\n[SUCCESS] Clean build out directory: ${Prj_Base}/outdir/${Board_Name}/\n"
		fi
	fi

	# 保存配置记录
	ini_file_write ${build_log_file} "${Prj_Name}" "${Board_Name}::conf" "${ConfFiles}" ' '
	i=0
	for tmp in ${PrjFile_Array[@]}; do
		ini_file_write ${build_log_file} "${Prj_Name}" "${Board_Name}::${tmp//\//::}_conf" "${ConfFile_Array[$i]}" ' '
		let i++
	done

#########################################################################################################

	# 生成 MakeFileParam
	MakeFileParam=(${MakeFileParam[@]} COMMON_PATH="`find_common_path ${Prj_Base} ${rtk_base}`")
	MakeFileParam=(${MakeFileParam[@]} PRJ_PATH=${Prj_Base})
	MakeFileParam=(${MakeFileParam[@]} ROOT_PATH=${rtk_base})
	MakeFileParam=(${MakeFileParam[@]} BOARD_PATH=${rtk_base}/architecture/board/${Board_Path})
	MakeFileParam=(${MakeFileParam[@]} CHIP_PATH=${rtk_base}/architecture/chip/${Chip_Path})
	MakeFileParam=(${MakeFileParam[@]} ARCH_PATH=${rtk_base}/architecture/arch/${Rules_Path})
	MakeFileParam=(${MakeFileParam[@]} CC_PREFIX=${ToolChain%*gcc})
	for tmp in ${ConfFile_Array[@]}; do MakeFileParam=(${MakeFileParam[@]} CONF_FILE+=${Prj_Base}/${tmp}); done

	RebuildParam="${MakeFileParam[@]} build"
	if (( ${#Param_Source_Array[@]} > 0 )); then
		MakeFileParam=(${MakeFileParam[@]} ${Param_Source_Array[@]})
	else
		MakeFileParam=(${MakeFileParam[@]} "build")
	fi

	# 编译过程
	if [ "${Build_List}" != "1" ]; then
		echo -e "\n  ----==== \033[36m${Prj_Path}\033[0m ====----"
		make -s -C ${Prj_Base} ${MakeFileParam[@]} || {
			[ -f ${Prj_Base}/outdir/${Board_Name}/autoconf.h ] && cat "${Prj_Base}/outdir/${Board_Name}/autoconf.h" > "${rtk_base}/debug/autoconf.h"
			return 1
		}

		if (echo ${MakeFileParam[@]} | grep -q -e ' mset='); then
			exit 0
		fi
	fi

	# 输出到 debug 文件夹的参数
	mkdir -p  ${rtk_base}/debug
	Prj_Name=$(basename ${Prj_Path})

	# 复制 bin 目录下的文件
	if [ "${Build_List}" != "1" ] && [ -d ${PWD}/bin ]; then
		for tmp in `find ${PWD}/bin/ -maxdepth 1 -type f -name "${Prj_Name}-${Board_Name}.*"`; do
			cp ${tmp} ${rtk_base}/debug/project.${tmp##*.}
		done
	fi

	# 生成符号表到 ${PWD}/bin/app_symbols.ld
	if [ "${Build_List}" != "1" ] && [ -d ${Prj_Base}/outdir/${Board_Name} ]; then
		for tmp in `find ${Prj_Base}/outdir/${Board_Name} -maxdepth 1 -type f -name "${Prj_Name}.*"`; do
			cp ${tmp} ${rtk_base}/debug/project.${tmp##*.}
		done
		[ -f ${Prj_Base}/outdir/${Board_Name}/autoconf.h ] && cat "${Prj_Base}/outdir/${Board_Name}/autoconf.h" > "${rtk_base}/debug/autoconf.h"
		[ -f ${rtk_base}/debug/project.elf ] && readelf ${rtk_base}/debug/project.elf -s > ${rtk_base}/debug/symbols.txt
		
		if [ -f  ${rtk_base}/debug/symbols.txt ] && [[ "${MakeFileParam[@]}" =~ 'release' ]]; then
			local symb_Num
			local symb_Value
			local symb_Size
			local symb_Type
			local symb_Bind
			local symb_Vis
			local symb_Ndx
			local symb_Name
			local start=0

			tmp=${PWD}/bin/${Prj_Name}-${Board_Name}-symbols.ld
			echo "/** Automatically generated file by $(basename ${BASH_SOURCE}). Do not edit!" > ${tmp}
			echo " * symbols for:" >> ${tmp}
			echo " * Proj:  ${Prj_Path}" >> ${tmp}
			echo " * Board: ${Board_Path}" >> ${tmp}
			echo " * Chip:  ${Chip_Path}" >> ${tmp}
			echo " * Rule:  ${Rules_Path}" >> ${tmp}
			echo " * ToolChain: ${ToolChain}" >> ${tmp}
			echo " */" >> ${tmp}

			echo -e "\r\n/* function: */" >> ${tmp}
			cat ${rtk_base}/debug/symbols.txt |\
			while read symb_Num symb_Value symb_Size symb_Type symb_Bind symb_Vis symb_Ndx symb_Name; do
				[ "$symb_Size" == "'.symtab'" ] && start=1
				if [ "$start" == "1" ] && [ "$symb_Size" != "0" ] && [ "$symb_Type" == "FUNC" ] && [ "$symb_Bind" == "GLOBAL" ] && [ "$symb_Vis" == "DEFAULT" ] && [ "${symb_Name:0:1}" != "_" ]; then
					echo "$symb_Name = 0x$symb_Value;" >> ${tmp}
				fi
			done

			echo -e "\r\n/* object: */" >> ${tmp}
			cat ${rtk_base}/debug/symbols.txt |\
			while read symb_Num symb_Value symb_Size symb_Type symb_Bind symb_Vis symb_Ndx symb_Name; do
				[ "$symb_Size" == "'.symtab'" ] && start=1
				if [ "$start" == "1" ] && [ "$symb_Size" != "0" ] && [ "$symb_Type" == "OBJECT" ] && [ "$symb_Bind" == "GLOBAL" ] && [ "$symb_Vis" == "DEFAULT" ] && [ "${symb_Name:0:1}" != "_" ]; then
					echo "$symb_Name = 0x$symb_Value;" >> ${tmp}
				fi
			done
		fi
	fi

	# 显示 APP
	echo -e "Proj:  \033[33m${Prj_Path}\033[0m"
	echo -e "Board: \033[33m${Board_Path}\033[0m"
	echo -e "Chip:  \033[33m${Chip_Path}\033[0m"
	echo -e "Rule:  \033[33m${Rules_Path}\033[0m"
	echo -e "ToolChain: \033[33m${ToolChain}\033[0m"
	# 显示配置的文件
	i=0
	for tmp in ${PrjFile_Array[@]}; do
		echo -e "${tmp}-conf = \033[33m${ConfFile_Array[$i]}\033[0m"
		let i++
	done
	echo

	if [ "${Build_List}" != "1" ]; then
		# 生成输出脚本到 ./.rebuild.sh
		if [ ! -f ./.rebuild.sh ]; then
			touch ./.rebuild.sh && chmod +x ./.rebuild.sh && echo -e '#!/bin/bash \nclear \\' > ./.rebuild.sh
		fi
		if !(cat ./.rebuild.sh | grep -q -e " make -j -s -C ${Prj_Base} ${MakeFileParam[0]} ${MakeFileParam[1]} ${MakeFileParam[2]} ${MakeFileParam[3]}"); then
			echo "&& echo -e \"\n\${BASH_SOURCE}:\${LINENO}\n  ----==== \033[36m${Prj_Path}\033[0m ====----\" && make -j -s -C ${Prj_Base} ${RebuildParam} \\" >> ./.rebuild.sh
		fi
	fi
}









#########################################################################################################
#########################################################################################################

function check_and_create() {
	# 通过终端运行脚本时，检查 $PWD 下是否存在某个文件，如果没有则提示是否要创建一个新的记录并由用户输入，选项有 yes/NO，默认为 NO 返回 1，输入为 yes 返回0
	# check_and_create <file_path> [prompt]
	# 使用示例:
	# if check_and_create "config.ini" "配置文件不存在,是否创建?"; then
	#     echo "创建新文件..."
	# else
	#     echo "操作取消"
	#     exit 1
	# fi
	
	local file_path="${1}"
	local prompt="${2:-'要创建新记录吗?'}"

	# 检查文件是否存在
	if [[ ! -f "${file_path}" ]]; then
		# 提示用户
		read -p "${prompt} (Yes/NO): " answer

		# 处理输入
		case "${answer}" in
			Yes)
				return 0
				;;
			*)
				return 1
				;;
		esac
	fi

	return 0
}

print_local_functions() {

	local Param=$1
	local MatchLogs=0
	local Key
	local SplitName
	local SedLine

	SedLine=`sed -n -e "/^function ${Param}.*()/=" ${BASH_SOURCE} | sed -n '1p'`

	if [ -n "${SedLine}" ]; then
		echo -e "${BASH_SOURCE}:${SedLine}"
		while [ -n "${Param}" ]; do
			let SedLine++
			Param=`sed -n ${SedLine}p $BASH_SOURCE | grep "#"`
			Param=${Param//	/}
			echo "    ${Param}"
		done
		echo
	fi
}
if [ "$1" == "-h" ]; then

	echo -e "\n\033[35m--== Detail for function ==--\033[0m\n"
	print_local_functions "--build" -a

else

	if check_and_create ${build_log_file} "Do you want to create a new record?"; then
		--build $@
	fi

fi
